﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LearnCSharp
{
    /*
        * *************************************************************************************
        * *************************************************************************************
        *                                      Enumération
        * *************************************************************************************
        * *************************************************************************************
    */

    // Enum
    enum Race { Humain, Nain = 10, Elfe = 20 }

    // Enum binaire
    enum RaceClasse
    {
        Humain = 0x01,
        Orc = 0x02,
        Bien = 0x04,
        Mal = 0x08
    }

    /// <summary> EnumCSharp </summary>
    public class EnumCSharp
    {
        private void UseEnum()
        {
            // Déclaration
            Race r0 = new Race();

            // Test enum
            if (r0 == Race.Humain)
                Console.WriteLine(" Enum : Humain");

            // Initialisation
            Race r = Race.Humain;

            // Test enum par valeur
            if (r == 0)
                Console.WriteLine(" Enum : Humain");

            // Affichage Enum
            Console.WriteLine(" Enum : {0}", r.ToString());

            // Incrémentation Enum
            r++;
            Console.WriteLine(" Enum : {0}", r.ToString());

            r += 9;
            Console.WriteLine(" Enum : {0}", r.ToString());

            // Cast Enum
            r = (Race)20;
            Console.WriteLine(" Enum : {0}", r.ToString());

            r = (Race)666;
            Console.WriteLine(" Enum : {0}", r.ToString());

            // Variable de type Valeur
            Race r1 = Race.Humain;
            Race r2 = Race.Nain;

            r1 = r2;
            r2 = Race.Elfe;
            Console.WriteLine(" Enum : {0}", r1.ToString());

            // Format (enum || valeur enum -> string("g") || string valeur("d"))
            r1 = Race.Humain;
            string s = Enum.Format(typeof(Race), 10, "g");
            Console.WriteLine(" Format Enum : {0}", s);

            string s2 = Enum.Format(typeof(Race), r1, "d");
            Console.WriteLine(" Format Enum : {0}", s2);

            // Parse (string -> enum)
            Race c3 = (Race)Enum.Parse(typeof(Race), "Humain", false);
            Console.WriteLine(" Parse Enum : {0}", c3.ToString());

            // GetName (enum || valeur enum-> string)
            string s3 = Enum.GetName(typeof(Race), 10);
            Console.WriteLine(" GetName Enum : {0}", s3.ToString());

            string s31 = Enum.GetName(typeof(Race), Race.Humain);
            Console.WriteLine(" GetName Enum : {0}", s31.ToString());

            // IsDefined
            bool b = Enum.IsDefined(typeof(Race), 33);
            Console.WriteLine(" IsDefined Enum : {0}", b.ToString());

            bool b2 = Enum.IsDefined(typeof(Race), Race.Humain);
            Console.WriteLine(" IsDefined Enum : {0}", b2.ToString());

            // GetUnderlyingType : renvoie le type définie pour les valeur de l'enum
            System.Type T1 = Enum.GetUnderlyingType(typeof(Race));
            Console.WriteLine(" GetUnderlyingType Enum : {0}", T1.ToString());

            // ToObject (valeur enum -> enum)
            Race c4 = (Race)Enum.ToObject(typeof(Race), 10);
            Console.WriteLine(" ToObject Enum : {0}", c4.ToString());

            // Parcours Enum
            foreach (string sfe in Enum.GetNames(typeof(Race)))
            {
                Console.WriteLine(" foreach Enum : {0}", sfe);
            }

            // Exception : ArgumentException
            string s4 = "666";
            try
            {
                Race c5 = (Race)Enum.Parse(typeof(Race), s4);
            }
            catch (ArgumentException e)
            {
                Console.WriteLine(" Exception EnumBiniare : {0}", e.ToString());
            }


            Console.ReadLine();
        }


        // Enum Binaire ( focément des valeurs de puissance de 2)
        // Rappel : enum RaceClasse { Humain  = 0x01, Orc     = 0x02, Bien    = 0x04, Mal     = 0x08 }

        private void UseEnumBinaire()
        {
            // Association 
            RaceClasse rc1 = RaceClasse.Humain | RaceClasse.Bien;
            // Humain | Bien = 1 | 4 = 0001 | 0100 = 0101 = 5
            Console.WriteLine(" EnumBiniare : {0}", rc1.ToString());

            // Test
            // 5 & 1 = 0101 & 0001 = 0001 = 1
            if ((rc1 & RaceClasse.Humain) > 0)
                Console.WriteLine(" Test EnumBiniare : {0}", rc1.ToString());

            if ((rc1 & RaceClasse.Humain) > 0 // 5 & 1 = 0101 & 0001 = 0001 = 1
                &&
                (rc1 & RaceClasse.Bien) > 0) // 5 & 4 = 0101 & 0100 = 0100 = 4
                Console.WriteLine(" Test EnumBiniare : {0}", rc1.ToString());

            // Exception : ArgumentException
            string s = "Humain,666";
            try
            {
                RaceClasse rc2 = (RaceClasse)Enum.Parse(typeof(RaceClasse), s);
            }
            catch (ArgumentException e)
            {
                Console.WriteLine(" Exception EnumBiniare : {0}", e.ToString());
            }

            Console.ReadLine();
        }
    }
}
